package com.zw.yzk.kabu.view.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

@SuppressLint("ClickableViewAccessibility")
public class CustomSwitch extends View {
    private float scale;
    private float width;
    private float height;
    private float strokeWidth;

    private boolean touch;
    private boolean status;
    private boolean pre_status;

    private Paint point_bound_paint;
    private Paint point_circle_paint;
    private Paint stroke_paint;
    private Paint white_paint;
    private Paint green_paint;
    private long down_time;

    public CustomSwitch(Context context) {
        this(context, null);
    }

    public CustomSwitch(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomSwitch(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        scale = 0f;
        status = false;
        pre_status = false;

        strokeWidth = 4;

        //描边
        stroke_paint = new Paint();
        stroke_paint.setColor(Color.parseColor("#F2F2F2"));
        stroke_paint.setAntiAlias(true);
        //白色
        white_paint = new Paint();
        white_paint.setColor(Color.WHITE);
        white_paint.setAntiAlias(true);
        //绿色
        green_paint = new Paint();
        green_paint.setColor(Color.parseColor("#4BD963"));
        green_paint.setAlpha(0);
        green_paint.setAntiAlias(true);
        //圆圈描边
        point_bound_paint = new Paint();
        point_bound_paint.setColor(Color.parseColor("#F2F2F2"));
        point_bound_paint.setAntiAlias(true);
        //白色圆圈
        point_circle_paint = new Paint();
        point_circle_paint.setColor(Color.WHITE);
        point_circle_paint.setAntiAlias(true);
    }

    public void setSwitchStatus(boolean status) {
        this.status = status;
        this.pre_status = status;
        this.scale = status ? 1f : 0f;

        invalidate();
    }

    public void setStrokeWidth(float strokeWidth) {
        this.strokeWidth = strokeWidth;

        invalidate();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
                            int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        width = getWidth();
        height = getHeight();
    }


    private void drawPoint(Canvas canvas) {
        float radius = height / 2f;
        canvas.drawCircle(radius + scale * (width - radius * 2f), height / 2f, radius, point_bound_paint);
        canvas.drawCircle(radius + scale * (width - radius * 2f), height / 2f, radius
                - strokeWidth, point_circle_paint);
    }


    private void drawBackground(Canvas canvas) {
        green_paint.setAlpha((int) (scale * 255));
        RectF rect = new RectF(0, 0, width, height);
        if (green_paint.getAlpha() == 0) {
            RectF solid = new RectF(strokeWidth, strokeWidth, width - strokeWidth, height - strokeWidth);
            canvas.drawRoundRect(rect, height / 2, height / 2, stroke_paint);
            canvas.drawRoundRect(solid, height / 2, height / 2, white_paint);
            canvas.drawRoundRect(solid, height / 2, height / 2, green_paint);
        } else {
            canvas.drawRoundRect(rect, height / 2, height / 2, white_paint);
            canvas.drawRoundRect(rect, height / 2, height / 2, green_paint);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBackground(canvas);
        drawPoint(canvas);
    }

    private boolean touchPoint(float touch) {
        float point_center_x = height / 2f + scale * (width - height);
        boolean result = touch >= point_center_x
                && touch <= point_center_x + height / 2f;
        return result;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        //当CustomSwitch获得点击事件后禁止父View获取touch事件，防止滑动过程中被父控件抢走点击事件
        getParent().requestDisallowInterceptTouchEvent(true);
        return super.dispatchTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                down_time = SystemClock.elapsedRealtime();
                touch = touchPoint(event.getX());
                break;
            case MotionEvent.ACTION_MOVE:
                if (touch) {
                    float x;
                    if (event.getX() < 0) {
                        x = 0;
                    } else if (event.getX() > width) {
                        x = width;
                    } else {
                        x = event.getX();
                    }
                    scale = x / width;
                    status = scale > 0.5f;
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                if (touch) {
                    scale = status ? 1 : 0;
                    invalidate();
                }
                touch = false;
                if (SystemClock.elapsedRealtime() - down_time < 300) {
                    scale = status ? 0 : 1;
                    invalidate();
                    status = (scale == 1);
                }
                if (pre_status != status) {
                    if (listener != null) {
                        listener.OnStateChange(status);
                    }
                    pre_status = status;
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                touch = false;
                break;
            default:
                break;
        }
        return true;
    }

    private OnStateChangeListener listener;

    public void setOnStateChageListener(OnStateChangeListener listener) {
        this.listener = listener;
    }

    public interface OnStateChangeListener {
        void OnStateChange(boolean status);
    }
}
